/**
 * Promise 默认是一个类 需要new调用  创建的实例上有个then方法， 在new的过程中需要传入 一个执行器
 * PromiseA+ 规范
 * 1-- promise中有个value描述成功的原因， reason是一个失败的原因
 * 2-- promise 出现异常会执行失败逻辑
 * 3-- 三个状态  pending  fulfilled  rejected
 * 4-- 状态不为pending时 无法继续被修改
 * 5--executor会立刻执行 并且传入两个参数resolve reject
 * 6--then方法返回的结果如果不是promise 则将这个结果传递给下一次then的成功
 * 7--then方法执行出错，则将错误传递给下次then的失败
 * 8--then方法返回promise 则根据promise的状态决定下一次then的成功还是失败
 * 
*/
const fs = require('fs').promises
const path = require('path')

const Promise = require('./my-promise/index')


// const p1 = new Promise((resolve, reject) => {
//     console.log(1);
//     // reject('error')
//     setTimeout(() => {
//         // resolve('success')
//     }, 1000)
// })
// console.log(2);
// p1.then(v => {
//     console.log('成功', v);
// }, r => {
//     console.log('失败', r);
// })
// p1.then(v => {
//     console.log('成功2', v);
// }, r => {
//     console.log('失败2', r);
// })

// function readFile(url, encoding) {
//     return new Promise((resolve, reject) => {
//         fs.readFile(url, encoding, function (err, data) {
//             if (err) return reject(err)
//             resolve(data)
//         })
//     })
// }


// readFile(path.resolve(__dirname, 'file.txt'), 'utf8').then(data => {
//     return readFile(path.resolve(__dirname, data1), 'utf8')
// }).then(e => {
//     console.log('success', e)
// }, r => { console.log('error', r) })


// function testDfd() {
//     let dfd = Promise.deferred()
//     setTimeout(() => {
//         dfd.resolve('success')
//     }, 200)
//     return dfd.promise
// }

// testDfd().then(console.log)


// let p1 = new Promise((resolve, reject) => {
//     reject('error')
// }).catch(console.log)

// Promise.resolve(new Promise(res => res('成功'))).then(console.log)
// Promise.reject(new Promise((_, rej) => rej('失败'))).catch(console.log)


// Promise.all([p1, p2, p3]).then(res => {
//     console.log(res) //[1,2,3]
// }).catch(console.log)


// Promise.reject('哈哈').finally(() => {
//     // return Promise.resolve('finally中的哈哈')
//     return new Promise((r) => {
//         setTimeout(() => {
//             r('finally中的哈哈')
//         }, 2000)
//     })
// }).then((r) => {
//     console.log('成功', r)
// }).catch((r) => {
//     console.log('失败', r)
// })

/**
 * finally的几种情况
 * finally 不接受任何参数
 * resolve(x)：finally回调中没有返回除promise的任意值  then接受x
 *           finally回调中返回promise.成功y  then接受x
 *           finally回调中返回promise.失败y  catch接受y
 * reject(x)：finally回调中没有返回除promise的任意值  catch接受x
 *           finally回调中返回promise.成功y  catch接受x
 *           finally回调中返回promise.失败y  catch接受y
*/


//  将函数转为promise


// function promisify(fn) {
//     return function (...args) {
//         return new Promise((resolve, reject) => {
//             fn(...args, (err, data) => {
//                 if (err) return reject(err)
//                 resolve(data)
//             })
//         })
//     }

// }

// function promisifyAll(obj) {
//     for (let key in obj) {
//         if (typeof obj[key] === 'function') {
//             obj[key] = promisify(obj[key])
//         }
//     }

// }
// promisifyAll(fs)
// fs.readFile('./age.txt', 'utf-8').then(res => {
//     console.log(res)
// })


// Promise.race([
//     fs.readFile('./age.txt', 'utf-8'),
//     fs.readFile('./name1.txt', 'utf-8')]).then((res) => {
//         console.log(res)
//     }).catch(e => {
//         console.log(e)
//     })
/**
 * race  无论成功失败  返回最先拿到状态的promise 
*/

/*
promise.race应用场景 ==> 请求功能超时， promise是没法中断执行的。 
无论如何都会执行完毕，只是不采用promise的成功或者失败的结果

**/

//0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-超时功能

let p1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve('promise')
    }, 2000)
})

let warp = function (p) {
    let abort
    let p2 = new Promise((_, rej) => {
        abort = rej
    }).then(e => console.log(e), r => console.log(r))
    let returnPromise = Promise.race([p, p2])
    returnPromise.abort = abort
    return returnPromise
}

let newPromise = warp(3000, p1)
setTimeout(() => {
    newPromise.abort('请求超时')
}, 200)

//-=-=--------如何中断一个promise 不让他执行then
// let done = new Promise(res => {
//     return new Promise(() => { })
// })
// done.then(console.log)